#ifndef frm_filler_H
#define frm_filler_H

#include "svl.h"
#include "frm.h"

namespace frm { namespace filler {

///////////////////////////////////////////////////////////////////////////////

struct TBase : public svl::TArray_Object , public TDebug
{
	virtual ~TBase() {}
	virtual TBase *TBase_NewCopy() = 0;
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint) = 0;
	virtual bool   TBase_IsTransparent() = 0;
};

///////////////////////////////////////////////////////////////////////////////

struct TBaseArray : public TDebug
{
	void Add(TBase *V,bool EnDelete) { a.Add(V,EnDelete);}
	void Delete(int N)               { a.Delete(N);}
	//
	void Clear() { a.Clear();}
	int  Count() { return a.Numb();}
	//
	TBase &Get(int N) { return *(TBase*)a.Get(N);}
	TBase &operator[](int N) { return Get(N);}
	//
	void CopyFrom(TBaseArray &V);

private:
	svl_Except;
	svl::TArray a;
};

///////////////////////////////////////////////////////////////////////////////

struct TEmpty : public TBase
{
	TEmpty()          {}
	TEmpty(TEmpty &V) {}
	//
	virtual TBase *TBase_NewCopy() { return new TEmpty(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint){}
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TColor : public TBase
{
	grf::TColor Value;
	//
	TColor(int R,int G,int B) { Value = grf::TColor(R,G,B);}
	TColor(grf::TColor V)     { Value = V;}
	TColor(TColor     &V)     { Value = V.Value;}
	//
	virtual TBase *TBase_NewCopy() { return new TColor(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return false;}
	//
	virtual svl::TInfoParam AddInfoTo(svl::TInfoParam Info);
};

///////////////////////////////////////////////////////////////////////////////

struct TLineVertCenter : public TBase
{
	grf::TPen Pen;
	//
	TLineVertCenter(int R,int G,int B,int W = 1) :Pen(grf::TColor(R,G,B),W) {}
	TLineVertCenter(grf::TColor Color,int W = 1) :Pen(Color,W) {}
	TLineVertCenter(TLineVertCenter &V) :Pen(V.Pen) {}
	//
	virtual TBase *TBase_NewCopy() { return new TLineVertCenter(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TLineVertRight : public TBase
{
	grf::TPen Pen;
	//
	TLineVertRight(int R,int G,int B,int W = 1) :Pen(grf::TColor(R,G,B),W) {}
	TLineVertRight(grf::TColor Color,int W = 1) :Pen(Color,W) {}
	TLineVertRight(TLineVertRight &V) :Pen(V.Pen) {}
	//
	virtual TBase *TBase_NewCopy() { return new TLineVertRight(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TLineVertLeft : public TBase
{
	grf::TPen Pen;
	//
	TLineVertLeft(int R,int G,int B,int W = 1) :Pen(grf::TColor(R,G,B),W) {}
	TLineVertLeft(grf::TColor Color,int W = 1) :Pen(Color,W) {}
	TLineVertLeft(TLineVertLeft &V) :Pen(V.Pen) {}
	//
	virtual TBase *TBase_NewCopy() { return new TLineVertLeft(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TLineHorzTop : public TBase
{
	grf::TPen Pen;
	//
	TLineHorzTop(int R,int G,int B,int W = 1) :Pen(grf::TColor(R,G,B),W) {}
	TLineHorzTop(grf::TColor Color,int W = 1) :Pen(Color,W) {}
	TLineHorzTop(TLineHorzTop &V) :Pen(V.Pen) {}
	//
	virtual TBase *TBase_NewCopy() { return new TLineHorzTop(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TLineHorzBottom : public TBase
{
	grf::TPen Pen;
	//
	TLineHorzBottom(int R,int G,int B,int W = 1) :Pen(grf::TColor(R,G,B),W) {}
	TLineHorzBottom(grf::TColor Color,int W = 1) :Pen(Color,W) {}
	TLineHorzBottom(TLineHorzBottom &V) :Pen(V.Pen) {}
	//
	virtual TBase *TBase_NewCopy() { return new TLineHorzBottom(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TLineHorzCenter : public TBase
{
	grf::TPen Pen;
	//
	TLineHorzCenter(int R,int G,int B,int W = 1) :Pen(grf::TColor(R,G,B),W) {}
	TLineHorzCenter(grf::TColor Color,int W = 1) :Pen(Color,W) {}
	TLineHorzCenter(TLineHorzCenter &V) :Pen(V.Pen) {}
	//
	virtual TBase *TBase_NewCopy() { return new TLineHorzCenter(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TFrameRect : public TBase
{
	grf::TColor Value;
	//
	TFrameRect(int R,int G,int B) { Value = grf::TColor(R,G,B);}
	TFrameRect(grf::TColor V)     { Value = V;}
	TFrameRect(TFrameRect &V)     { Value = V.Value;}
	//
	virtual TBase *TBase_NewCopy() { return new TFrameRect(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
	//
	virtual svl::TInfoParam AddInfoTo(svl::TInfoParam Info);
};

///////////////////////////////////////////////////////////////////////////////

struct TColorLevel : public TBase
{
	TColorLevel()               {}
	TColorLevel(TColorLevel &V) {}
	//
	virtual TBase *TBase_NewCopy() { return new TColorLevel(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return false;}
};

///////////////////////////////////////////////////////////////////////////////

struct TColorLevelFrame : public TBase
{
	grf::TColor FrameColor;
	//
	TColorLevelFrame(grf::TColor FrameColor) { this->FrameColor = FrameColor;}
	TColorLevelFrame(TColorLevelFrame &V)    { this->FrameColor = V.FrameColor;}
	//
	virtual TBase *TBase_NewCopy() { return new TColorLevelFrame(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return false;}
};

///////////////////////////////////////////////////////////////////////////////

struct TRoundRect : public TBase
{
	grf::TPen   Pen;
	grf::TBrush Brush;

	TRoundRect(grf::TColor FrameColor,grf::TColor FillColor) :Pen(FrameColor),Brush(FillColor) {}
	TRoundRect(TRoundRect &V) :Pen(V.Pen),Brush(V.Brush) {}
	//
	virtual TBase *TBase_NewCopy() { return new TRoundRect(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return true;}
};

///////////////////////////////////////////////////////////////////////////////

struct TFillImage : public TBase
{
	grf::TImage &Image;
	//
	TFillImage(grf::TImage &V) :Image(V) {}
	TFillImage(TFillImage  &V) :Image(V.Image) {}
	//
	virtual TBase *TBase_NewCopy() { return new TFillImage(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return Image.IsTransparent();}

private:
	svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TImage : public TBase
{
	grf::TImage &Image;
	//
	TImage(grf::TImage &V) :Image(V) {}
	TImage(TImage      &V) :Image(V.Image) {}
	//
	virtual TBase *TBase_NewCopy() { return new TImage(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return Image.IsTransparent();}
};

///////////////////////////////////////////////////////////////////////////////

struct TImageCenter : public TBase
{
	grf::TImage &Image;
	//
	TImageCenter(grf::TImage  &V) :Image(V) {}
	TImageCenter(TImageCenter &V) :Image(V.Image) {}
	//
	virtual TBase *TBase_NewCopy() { return new TImageCenter(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return Image.IsTransparent();}
};

/////////////////////////////////////////////////////////////////////////////////

struct TImageBorderOld : public TBase
{
	grf::TImageGdiP* Images[9];
	//
	TImageBorderOld(grf::TImageGdiP **V) { for(int i=0;i<9;i++) Images[i]=V[i]; }
	TImageBorderOld(TImageBorderOld &V) { for(int i=0;i<9;i++) Images[i]=V.Images[i]; }
	//
	virtual TBase *TBase_NewCopy() { return new TImageBorderOld(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent();
};

/////////////////////////////////////////////////////////////////////////////////

struct TImageBorder : public TBase
{
	grf::TImageGdiP* ImageMain;
	int t, r, b, l;
	bool multi;
	//
	TImageBorder(grf::TBorderInfo *V) { ImageMain=V->image; t=V->t; r=V->r; b=V->b; l=V->l; multi = V->multi; }
	TImageBorder(TImageBorder &V) { ImageMain = V.ImageMain; t=V.t; r=V.r; b=V.b; l=V.l; multi = V.multi; }
	//
	virtual TBase *TBase_NewCopy() { return new TImageBorder(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent();
	//
	void DrawHorzT( grf::TRect &RTo, TPaint &Paint );
	void DrawHorzB( grf::TRect &RTo, TPaint &Paint );
	void DrawVertL( grf::TRect &RTo, TPaint &Paint );
	void DrawVertR( grf::TRect &RTo, TPaint &Paint );
	void DrawSquare( grf::TRect &RTo, TPaint &Paint );
};

///////////////////////////////////////////////////////////////////////////////

struct TArray : public TBase
{
	TArray()          {}
	TArray(TArray &V) { a.CopyFrom(V.a);}
	//
	TArray &Clear()              { a.Clear(); return *this;}
	TArray &Add (const TBase &V) { a.Add(const_cast<TBase&>(V).TBase_NewCopy(),true); return *this;}
	TArray &Link(const TBase *V) { a.Add(const_cast<TBase*>(V),false); return *this;}
	//
	virtual TBase *TBase_NewCopy() { return new TArray(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent();
	//
	virtual svl::TInfoParam AddInfoTo(svl::TInfoParam Info);

private:
	TBaseArray a;
};

///////////////////////////////////////////////////////////////////////////////

struct TArrayMemDC : public TBase
{
	TArrayMemDC()               {}
	TArrayMemDC(TArrayMemDC &V) { a.CopyFrom(V.a);}
	//
	TArrayMemDC &Clear()             { a.Clear(); return *this;}
	TArrayMemDC &Add(const TBase &V) { a.Add(const_cast<TBase&>(V).TBase_NewCopy(),true); return *this;}
	//
	virtual TBase *TBase_NewCopy() { return new TArrayMemDC(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent();

private:
	TBaseArray a;
};

///////////////////////////////////////////////////////////////////////////////

struct TOddEven : public TBase
{
	grf::TColor Odd,Even;
	//
	TOddEven() {}
	TOddEven(TOddEven &V) :Odd(V.Odd),Even(V.Even) {}
	//
	virtual TBase *TBase_NewCopy() { return new TOddEven(*this);}
	virtual void   TBase_Paint(TComponent &Component,TPaint &Paint);
	virtual bool   TBase_IsTransparent() { return false;}

private:
	svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TFiller : public TDebug , public svl::TPointer
{
	TFiller() { base = NULL;}
	~TFiller() { delete base;}
	//
	void SetNull() { delete base; base = NULL;}
	bool IsNull()  { return base == NULL;}
	//
	void   Set(const TBase &V) { delete base; base = ((TBase&)V).TBase_NewCopy();}
	void   Set(TFiller &V)     { delete base; base = V.base ? V.base->TBase_NewCopy() : NULL; }
	TBase *Get()               { return base;}
	// 
	void SetOrAdd(const TBase &V);
	void SetFromParent(TFiller &V);  
	//
	bool IsTransparent()                            { return base ? base->TBase_IsTransparent() : true;}
	void Paint(TComponent &Component,TPaint &Paint) { if (base) { base->TBase_Paint(Component,Paint);} }
	//
	virtual svl::TInfoParam AddInfoTo(svl::TInfoParam Info);
	//
	TFiller &operator=( const TFiller &a){ Set( const_cast<TFiller&>(a) ); return *this; };
private:
	TBase *base;
};

///////////////////////////////////////////////////////////////////////////////
}}

#endif
